"""
代理进程管理模块
负责启动、停止和监控代理服务器进程
"""
import os
import time
import subprocess
import psutil
import logging

# 配置日志
logger = logging.getLogger(__name__)


class ProxyProcessManager:
    def __init__(self, config_path='config.yaml'):
        self.config_path = config_path
        self.pid_file = 'proxy_server.pid'
        self.process = None
        # 导入ConfigManager来读取配置
        try:
            from ..config.manager import ConfigManager
            self.config_manager = ConfigManager(config_path)
        except ImportError:
            self.config_manager = None
            logger.warning("无法导入ConfigManager，将使用默认端口配置")
        logger.info(f"初始化代理进程管理器，配置文件: {config_path}, PID文件: {self.pid_file}")
    
    def start_proxy_process(self, host=None, port=None, log_level=None):
        """启动代理服务器进程"""
        if self.is_proxy_running():
            return True, "代理服务器已在运行"
        
        # 如果没有指定host和port，从配置文件读取
        if host is None or port is None:
            if self.config_manager:
                proxy_config = self.config_manager.get_proxy_config()
                if host is None:
                    host = proxy_config.get('host', '0.0.0.0')
                if port is None:
                    port = proxy_config.get('port', 8080)
            else:
                # 没有ConfigManager，使用默认值
                if host is None:
                    host = '0.0.0.0'
                if port is None:
                    port = 8080
        
        try:
            # 启动代理服务器作为子进程
            cmd = [
                'python', 'proxy_server.py',
                '--config', self.config_path
            ]
            
            # 只有在明确指定时才添加host和port参数
            if host != '0.0.0.0' or port != 8080:
                cmd.extend(['--host', host, '--port', str(port)])
            
            # 如果指定了日志级别，添加到命令行参数
            if log_level:
                cmd.extend(['--log-level', log_level])
            
            # 创建日志文件
            log_file = open('proxy_server.log', 'w')
            
            self.process = subprocess.Popen(
                cmd,
                stdout=log_file,
                stderr=subprocess.STDOUT,
                start_new_session=True  # 创建新的会话
            )
            
            # 保存PID到文件
            with open(self.pid_file, 'w') as f:
                f.write(str(self.process.pid))
            
            # 等待一小段时间确保进程启动
            time.sleep(0.5)
            
            if self.process.poll() is None:  # 进程仍在运行
                # 自动更新系统代理设置
                self._auto_update_system_proxy()
                return True, f"代理服务器启动成功，PID: {self.process.pid}"
            else:
                return False, "代理服务器启动失败"
                
        except Exception as e:
            return False, f"启动代理服务器时出错: {str(e)}"
    
    def stop_proxy_process(self):
        """停止代理服务器进程"""
        try:
            pid = self._get_saved_pid()
            if pid:
                try:
                    # 尝试优雅关闭
                    process = psutil.Process(pid)
                    process.terminate()
                    time.sleep(1)
                    
                    # 检查进程是否还在运行
                    if process.is_running():
                        # 强制终止
                        process.kill()
                        time.sleep(0.5)
                    
                    self._cleanup_pid_file()
                    return True, "代理服务器已停止"
                    
                except ProcessLookupError:
                    self._cleanup_pid_file()
                    return True, "代理服务器已停止"
            else:
                return True, "代理服务器未运行"
                
        except Exception as e:
            return False, f"停止代理服务器时出错: {str(e)}"
    
    def is_proxy_running(self):
        """检查代理服务器是否正在运行"""
        pid = self._get_saved_pid()
        if pid:
            try:
                return psutil.pid_exists(pid) and psutil.Process(pid).is_running()
            except:
                self._cleanup_pid_file()
                return False
        return False
    
    def get_proxy_status(self):
        """获取代理服务器状态"""
        if self.is_proxy_running():
            pid = self._get_saved_pid()
            try:
                process = psutil.Process(pid)
                return {
                    'running': True,
                    'pid': pid,
                    'status': process.status(),
                    'cpu_percent': process.cpu_percent(),
                    'memory_info': process.memory_info()._asdict()
                }
            except:
                return {'running': True, 'pid': pid}
        else:
            return {'running': False}
    
    def _get_saved_pid(self):
        """从文件中读取保存的PID"""
        try:
            if os.path.exists(self.pid_file):
                with open(self.pid_file, 'r') as f:
                    return int(f.read().strip())
        except:
            pass
        return None
    
    def _cleanup_pid_file(self):
        """清理PID文件"""
        try:
            if os.path.exists(self.pid_file):
                os.remove(self.pid_file)
        except:
            pass
    
    def restart_proxy_process(self, host=None, port=None, log_level=None):
        """重启代理服务器进程"""
        if self.is_proxy_running():
            # 先停止现有进程
            stop_success, stop_message = self.stop_proxy_process()
            if not stop_success:
                return False, f"停止代理服务器失败: {stop_message}"
            
            # 等待进程完全停止
            time.sleep(1)
        
        # 启动新进程
        return self.start_proxy_process(host, port, log_level)
    
    def _auto_update_system_proxy(self):
        """自动更新系统代理设置"""
        try:
            from .system_manager import SystemProxyManager
            
            system_manager = SystemProxyManager(self.config_path)
            success = system_manager.enable_proxy()
            
            if success:
                logger.info("自动更新系统代理设置成功")
            else:
                logger.warning("自动更新系统代理设置失败")
                
        except Exception as e:
            logger.warning(f"自动更新系统代理时出错: {e}")